/*
 * @Author: lp
 * @Date: 2022-01-24 17:23:31
 * @LastEditTime: 2022-06-25 16:31:40
 * @LastEditors: 瞿旺兴 18774621495@163.com
 * @Description: 字典
 * @FilePath: //nien-vue3-admin//src//store//modules//dicts.ts
 */
import { defineStore } from 'pinia'

import { getAddressAndService } from '@/api/system/singleAccount'
import { getDict as normalDict, praseStrEmpty } from '@/utils'
// #region
// 非常规字典接口
// #endregion
import { getQueryList } from '@/api/basicConfig/stateMaintanance'
import { listByCode, productsList, feeTypeList } from '@/api/expressManager/orderList'
import { amazonCodeList } from '@/api/expressManager/outSea'
import { listType } from '@/api/system/dict/type'
import { getAreaAndWareHouse } from '@/api/basicConfig/salesPrice'
import { PackageType } from '@/api/expressManager/outPutOrder'
// import { getData as getAccountNum } from '@/api/accountMaintain/accountMaintain'
// import { getDicts } from '@/api/system/dict/data'
import { getList } from '@/api/BusinessConfig/serviceProvider'
/* 业务员 */
import { queryBusinessManager, listUserTab } from '@/api/system/user'
// 打印代码
import { getPrintConfig, getData } from '@/api/BusinessConfig/serviceChannel'
// 查询产品分类列表
import { listClassify } from '@/api/basicConfig/productsClassify' 
// 查询销售产品分组列表
import { listGroup } from '@/api/basicConfig/productsGroup'
// 查询燃油列表
import { getFuelList } from '@/api/BusinessConfig/fuelMaintain'
import { listDeptTable } from '@/api/system/dept'
// 销售产品
import { getProductList } from '@/api/BusinessConfig/promotingProducts'
// 收款账户
import { collectionInfoList } from '@/api/finance/FinancialManagementTools'
// 员工下拉框
import { listUserTabDropDownBox } from '@/api/system/notice'
// 发货人地址和服务商渠道
// #endregion

/* 业务员 */
/**
 * 用于定义字典的具体类型
 * 1，普通字典，即通过系统管理字典管理定义的字典数据：
 *    url:字典管理中字典类型对应的字段即为请求地址
 * 2，自定义字典为其他字典，各字段意义：
 *    url:请求的接口地址
 * 	  resKey:结果数据对应的键名
 * 	  callBack:结果处理回调函数，会传入结果数组，也需要return 处理后的数组
 */
type DictDirect = {
	// 为字符串时：为请求的地址（常规字典，即通过系统管理下字典管理添加的字典，字典类型就是请求地址）；或者请求实例
	url: string | ((arg?: any) => Promise<any>);
	// 非常规字典必传
	resKey?: string;
	// 非常规字典携带的请求条件
	params?: unknown;
	// 非常规字典处理数据的函数
	callBack?: (res: [any]) => Array<any>;
	// 用于表格回选的默认值，表格的格式化选项里面包含dictLabel,dictValue则以传递的为准，否则就以这里的为准
	dictValue?: string;
	dictLabel?: string;
};
type DictType = Record<DictDirection, DictDirect>;
// 此枚举用于定义字典名称，键值不能重复
export enum DictDirection {
系统显示隐藏, 
是否禁用字典,
国家,
客户,
产品,
快递产品,
字典名称,
收货站点,
货物类型,
报价类型,
用户性别,
运输类型,
包裹状态,
账单状态,
产品类别,
数据来源,
扣件状态,
客户类型,
跟进人,
通用状态,
价格等级,
客户结算模式,
客户端开关,
收款账户,
员工信息,
服务商类型,
服务商,
计重规则,
打印服务,
产品状态,
录入邮编,
产品类型,
产品分类,
产品分组,
包裹类型,
操作类型,
操作状态,
通知公告,
通知状态,
// 部门列表,
账户状态,
发货人地址,
服务渠道,
AmazonCode,
pod状态,
费用名称,
产品运输类型,
任务组名,
币种,
任务状态,
燃油种类,
产品组,
费用收取方式,
计费方式,
收款币种,
任务分组,
执行策略,
是否并发,
柜子型号,
签入状态,
转运签入状态,
拣货状态,
信息类型,
卡派轨迹状态,
转运运输方式,
审批状态,
当前进度,
需求类型,
部门列表,
紧急程度,
付款方式,
大区,
销售产品,
方案类型,
预定状态,
重量模板计费方式,
开票状态,
轨迹类型,
付款状态,
员工
}
/**
 * 用于定义字典的具体类型
 */
export const dictInfo: DictType = {
  [DictDirection.付款状态]: { url: 'finance_pay_status', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.开票状态]: { url: 'sym_billing_status', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.方案类型]: { url: 'sym_plan_type', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.销售产品]: { url: getProductList, resKey: 'data', params: { pageNum: 0, pageSize: 0, status: 1 }, dictLabel: 'salesProductName', dictValue: 'salesProductCode' },
  [DictDirection.账单状态]: { url: 'finance_bill_status', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.系统显示隐藏]: { url: 'sys_show_hide', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.是否禁用字典]: { url: 'sys_normal_disable', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.国家]: { url: getQueryList, resKey: 'data', params: { pageNum: 0, pageSize: 0 }, dictValue: 'id', dictLabel: 'countryChName' },
  [DictDirection.客户]: { url: listByCode, resKey: 'data', dictLabel: 'customerName', dictValue: 'customerCode' },
  [DictDirection.字典名称]: { url: listType, resKey: 'data', params: { pageNum: 1, pageSize: 68 }, dictLabel: 'dictName', dictValue: 'dictType' },
  [DictDirection.收货站点]: { url: getAreaAndWareHouse,
    resKey: 'data',
    dictLabel: 'deptName',
    dictValue: 'deptId',
    callBack: (res:[any]) => {
      console.log('deptName')
      
      let data = []
      res.forEach(item => {
        if (item.children.length > 0) {
          item.children.forEach(() => {
            item.deptId = String(item.deptId)
          })
          data = data.concat(item.children)
        }
      })
      return data
    },
  },
  [DictDirection.大区]: { url: getAreaAndWareHouse,
    resKey: 'data',
    dictLabel: 'deptName',
    dictValue: 'deptId',
  },
  [DictDirection.货物类型]: { url: 'express_package_type', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.报价类型]: { url: 'express_quotation_type', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.用户性别]: { url: 'sys_user_sex' },
  [DictDirection.产品]: { url: productsList, resKey: 'data', params: { productType: 1 }, dictLabel: 'salesProductName', dictValue: 'salesProductCode' },
  [DictDirection.快递产品]: { url: productsList, resKey: 'data', params: { productType: 4 }, dictLabel: 'salesProductName', dictValue: 'salesProductCode' },
  [DictDirection.运输类型]: { url: 'order_transport_type', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.包裹状态]: { url: 'express_order_splitting_status', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.产品类别]: { url: 'express_products_type', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.数据来源]: { url: 'system_order_dataSource', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.扣件状态]: { url: 'system_order_fasteners', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.客户类型]: { url: 'clientManage_type', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.跟进人]: { url: listUserTab, resKey: 'data', params: { deptId: 99 }, dictLabel: 'nickName', dictValue: 'deptId' },
  [DictDirection.通用状态]: { url: 'system_status', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.价格等级]: { url: 'selling_price_grade', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.客户结算模式]: { url: 'client_manger_settlementMode', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.客户端开关]: { url: 'client_open_account', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },	
  [DictDirection.收款账户]: { url: collectionInfoList, resKey: 'data', params: { pageNum: 0, pageSize: 0 }, dictLabel: 'accountNo', dictValue: 'id' },
  [DictDirection.员工信息]: { url: queryBusinessManager, resKey: 'data', params: { status: 0 }, dictLabel: 'nickName', dictValue: 'userName' },
  [DictDirection.员工]: { url: listUserTabDropDownBox, resKey: 'data', params: { pageSize: 0, pageNum: 0 }, dictLabel: 'nickName', dictValue: 'userName' },
  [DictDirection.计重规则]: { url: 'businessConfig_weightRules_list', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  // [DictDirection.服务商类型]: { url: getPrintConfig, resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.服务商]: { url: getList, resKey: 'data', params: { pageSize: 0, pageNum: 0 }, dictLabel: 'serviceWholeName', dictValue: 'providerServiceCode' },
  [DictDirection.服务商类型]: { url: 'system_serviceproviders_type', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.打印服务]: { url: getPrintConfig, resKey: 'data', params: { status: 0 }, dictLabel: 'accountType', dictValue: 'id' },
  [DictDirection.产品状态]: { url: 'express_product_status', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.录入邮编]: { url: 'businessConfig_isEntryEmail_dict', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.产品类型]: { url: 'system_productClassification', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.产品分类]: { url: listClassify, resKey: 'data', params: { status: '1' }, dictLabel: 'classifyName', dictValue: 'classifyCode' },
  [DictDirection.产品分组]: { url: listGroup, resKey: 'data', params: { status: '1' }, dictLabel: 'groupName', dictValue: 'id' },
  [DictDirection.包裹类型]: { url: 'express_package_type', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.操作类型]: { url: 'sys_oper_type', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.操作状态]: { url: 'sys_common_status', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.通知公告]: { url: 'sys_notice_type', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictCode' },
  [DictDirection.通知状态]: { url: 'sys_notice_status', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictCode' },
  [DictDirection.账户状态]: { url: 'sys_orderPrint_status', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.发货人地址]: { url: getAddressAndService, resKey: 'sysAddressInfos', params: null, dictLabel: 'address1', dictValue: 'id' },
  [DictDirection.服务渠道]: { url: getData, params: { pageSize: 0, pageNum: 0 }, resKey: 'data', dictLabel: 'channelChName', dictValue: 'id' },
  [DictDirection.AmazonCode]: { url: amazonCodeList, params: {}, resKey: 'data', dictLabel: 'code', dictValue: 'code' },
  [DictDirection.pod状态]: { url: 'system_pod_type', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictCode' },
  [DictDirection.费用名称]: { url: feeTypeList, params: { status: 1 }, resKey: 'data', dictLabel: 'feeName', dictValue: 'feeValue' },
  [DictDirection.产品运输类型]: { url: 'product_transport_type', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.任务组名]: { url: 'sys_job_group', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.柜子型号]: { url: PackageType, params: { pageSize: 0, pageNum: 0 }, resKey: 'data', dictLabel: 'cabinetType', dictValue: 'cabinetType' },
  [DictDirection.签入状态]: { url: 'order_qr_status', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictCode' },
  [DictDirection.转运签入状态]: { url: 'order_zyOrder', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictCode' },
  [DictDirection.拣货状态]: { url: 'order_pickingStatu', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictCode' },
  [DictDirection.信息类型]: { url: 'system_msg_type', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictCode' },
  [DictDirection.卡派轨迹状态]: { url: 'system_event_status', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictCode' },
  [DictDirection.转运运输方式]: { url: 'trans_shipment_type', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.任务状态]: { url: 'sys_job_status', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.币种]: { url: 'system_priceUnit', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },

  [DictDirection.燃油种类]: { url: getFuelList,
    resKey: 'data',
    params: { status: 0 },
    dictLabel: 'fuelTypeChinese',
    dictValue: 'id',
    callBack: (res:any) => {
      let data = []
      data = res.data
      return data
    },
  },
  [DictDirection.产品组]: { url: 'product_group', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.费用收取方式]: { url: 'serviceChannel_collection_method', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.计费方式]: { url: 'serviceChannel_billingMethod_methods', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.收款币种]: { url: 'collection_currency', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.任务分组]: { url: 'sys_job_group', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.执行策略]: { url: 'execution_strategy', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.是否并发]: { url: 'concurrent_or_not', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.审批状态]: { url: 'approval_status', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.当前进度]: { url: 'current_progress', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.需求类型]: { url: 'demand_type', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.部门列表]: { url: listDeptTable,
    resKey: 'data',
    params: { pageSize: 0, pageNum: 0 },
    dictLabel: 'deptName',
    dictValue: 'deptId',
  },
  [DictDirection.紧急程度]: { url: 'degree_of_urgency', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.付款方式]: { url: 'payment_method', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.预定状态]: { url: 'express_cabinManage_status', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.重量模板计费方式]: { url: 'weight_component_billing_type', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  [DictDirection.轨迹类型]: { url: 'trajectory_type', resKey: 'data', dictLabel: 'dictLabel', dictValue: 'dictValue' },
  
} 

type dictReqCtrType = {
	[key: string]: Record<string, string>;
};
// 字典请求控制池
const dictReqCtr: dictReqCtrType = {}
const dicts = defineStore('dicts', {
  state() {
    const data = {}
    for (const key in DictDirection) {
      if (Object.prototype.hasOwnProperty.call(DictDirection, key)) {
        const index = DictDirection[key]
        data[index] = []
      }
    }
    return data
  },
  actions: {
    /**
		 * @description:
		 * @param {url} 字典地址
		 * @param {key} 请求结果的数据键名
		 * @return {promise}返回请求结果的数据
		 */
    getDict(url: string, key: string) {
      return normalDict(url)
      .then((res) => {
        if (res?.code === 200) {
          const data = res.data
          this[key] = data
          return data
        } 
        throw new Error(`${ DictDirection[key] }字典请求异常`)
      })
			
      .catch((err) => {
        console.log(err)
      })
    },
    async setDicts(key: DictDirection) {
      try {
        if (dictReqCtr[DictDirection[key]] === undefined) dictReqCtr[DictDirection[key]] = { status: 'init' }
        const reqStatus = dictReqCtr[DictDirection[key]].status
        // 当请求状态为init/reject时，才发送请求
        if (reqStatus === 'init' || reqStatus === 'reject') {
          const dict = dictInfo[key]
          let res = null
          dictReqCtr[DictDirection[key]].status = 'pendding'
          if ('resKey' in dict && typeof dict.url === 'function') {
            // 非常规字典
            res = await this.getCustomDict(dict, key)
          } else {
            // 常规字典
            res = await this.getNormalDict(dict.url, key)
          }
          dictReqCtr[DictDirection[key]].status = 'success'
          return res
        }
      } catch (error) {
        console.warn(`[store dict module]: ${ DictDirection[key] }字典请求错误:${ error }`)
        dictReqCtr[DictDirection[key]].status = 'reject'
      }
    },
    getCustomDict(arg: DictDirect, key) {
      const { url, resKey, callBack, params } = arg
      if (typeof url === 'function') {
        return url(params || undefined)
        .then(async (res) => {
          if (praseStrEmpty(resKey) !== '') {
            if (res?.code == 200) {
              let data = []
              if (typeof callBack === 'function') {
                data = await callBack(res[resKey])
              } else {
                data = res[resKey]
              }
              this[key] = data
              return data
            } 
            throw new Error(`${ url.name }方法请求异常`)
          } else {
            throw new Error(`${ url.name }方法请求不正确,非常规字典接口必须传入resKey,用来取得接口返回的字段`)
          }
        })
        .catch((err) => {
          console.log(err)
          this[key] = []
          return []
        })
      } 
      throw new Error('字典信息错误,请把url设置为接口请求方法')
    },
    getNormalDict(url, key) {
      this.getDict(url, key)
    },
  },
  getters: {
    getDictLabel(state) {
      return (arg: { value: string | number; dict: Array<any> | string|number; dictLabel?: string; dictValue?: string }) => {
        const { value, dict } = arg
        let { dictValue, dictLabel } = arg
        let dictOption = []
        if (Array.isArray(dict)) {
          dictOption = dict

          if (dictValue === undefined) {
            throw new Error(`获取字典${ dict }的字典取值dictValue错误`)
          }
          if (dictLabel === undefined) {
            throw new Error(`获取字典${ dict }的字典回选值dictLabel错误`)
          }
        } else if (dict in dictInfo) {
          this.setDicts(dict)
          if (dictValue === undefined) {
            dictValue = dictInfo[dict].dictValue
            if (dictValue === undefined) throw new Error(`${ DictDirection[dict] }字典未预设【dictValue】,回选错误`)
          }
          if (dictLabel === undefined) {
            dictLabel = dictInfo[dict].dictLabel
            if (dictLabel === undefined) throw new Error(`${ DictDirection[dict] }字典未预设【dictLabel】,回选错误`)
          }
          dictOption = state[dict]
        } else {
          throw new Error('字典错误，值无效')
        }
        let label = value
        for (const item of dictOption) {
          if (item[dictValue] === value) {
            label = item[dictLabel]
            break
          }
        }
        return label
      }
    },
    getDictOption(state) {
      return (key) => {
        if (key in dictInfo) {
          this.setDicts(key)
          return state[key]
        }
        throw new Error('字典未定义')
      }
    },
    
  },
})

export default dicts
